from typing import Annotated

from fastapi import APIRouter, HTTPException, Query, status

from app.crud.doctors import (
    create_doctor,
    create_modality,
    delete_doctor_by_id,
    delete_modality,
    get_all_doctors,
    get_all_modalities,
    get_doctor_by_user_id,
    get_doctors_by_additional_modality_codes,
    get_doctors_by_main_modality_codes,
    get_modality_by_code,
    update_doctor,
    update_modality,
    verify_doctor,
)
from app.models.doctors import ScheduleType, ShiftType
from app.schemas.doctors import (
    DoctorCreateSchema,
    DoctorListViewSchema,
    DoctorSchema,
    DoctorUpdateSchema,
    ModalityCreateSchema,
    ModalitySchema,
    ModalityUpdateSchema,
)

router = APIRouter()


@router.post("/modalities/", response_model=ModalitySchema, status_code=status.HTTP_201_CREATED)
async def create_modality_(modality_schema: ModalityCreateSchema):
    """Create a new modality"""
    return await create_modality(modality_schema)


@router.get("/modalities/", response_model=list[ModalitySchema])
async def read_modalities():
    """Get all modalities"""
    return await get_all_modalities()


@router.put("/modalities/{code}/", response_model=ModalitySchema)
async def update_modality_(code: str, modality_schema: ModalityUpdateSchema):
    """Update modality details"""
    modality = await get_modality_by_code(code)
    if modality is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Modality not found")
    return await update_modality(modality, modality_schema)


@router.delete("/modalities/{code}/", status_code=status.HTTP_204_NO_CONTENT)
async def delete_modality_(code: str):
    """Delete modality by code"""
    modality = await get_modality_by_code(code)
    if modality is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Modality not found")
    await delete_modality(modality)
    return


@router.get("/schedule-types/", response_model=list[str])
async def read_schedule_types():
    """Get all schedule types"""
    return [schedule_type.value for schedule_type in ScheduleType]


@router.get("/shift-types/", response_model=list[str])
async def read_shift_types():
    """Get all shift types"""
    return [shift_type.value for shift_type in ShiftType]


@router.get("/", response_model=list[DoctorListViewSchema])
async def read_doctors(offset: int = 0, limit: int = 40):
    """Get all doctors"""
    return await get_all_doctors(offset, limit)


@router.get("/main_modality/", response_model=list[DoctorListViewSchema])
async def read_doctors_by_main_modality_codes(code: Annotated[list[str], Query()] = []):
    """Get doctors by main modality codes"""
    return await get_doctors_by_main_modality_codes(code)


@router.get("/additional_modality/", response_model=list[DoctorListViewSchema])
async def read_doctors_by_additional_modality_codes(code: Annotated[list[str], Query()] = []):
    """Get doctors by additional modality codes"""
    return await get_doctors_by_additional_modality_codes(code)


@router.post("/", response_model=DoctorSchema, status_code=status.HTTP_201_CREATED)
async def create_doctor_(doctor_schema: DoctorCreateSchema):
    """Create a new doctor"""
    return await create_doctor(doctor_schema)


@router.get("/{user_id}/", response_model=DoctorSchema)
async def read_doctor(user_id: int):
    """Get doctor details by id"""
    doctor = await get_doctor_by_user_id(user_id)
    if doctor is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Doctor not found")
    return doctor


@router.put("/{user_id}/", response_model=DoctorSchema)
async def update_doctor_(user_id: int, doctor_schema: DoctorUpdateSchema):
    """Update doctor details"""
    doctor = await get_doctor_by_user_id(user_id)
    if doctor is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Doctor not found")
    return await update_doctor(doctor, doctor_schema)


@router.delete("/{user_id}/", status_code=status.HTTP_204_NO_CONTENT)
async def delete_doctor(user_id: int):
    """Delete doctor by id"""
    doctor = await get_doctor_by_user_id(user_id)
    if doctor is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Doctor not found")
    await delete_doctor_by_id(user_id)
    return


@router.patch("/verify/{user_id}/", status_code=status.HTTP_204_NO_CONTENT)
async def verify_doctor_(user_id: int):
    """Verify doctor by id"""
    return await verify_doctor(user_id)
